home *** CD-ROM | disk | FTP | other *** search
/ Tech Arsenal 1 / Tech Arsenal (Arsenal Computer).ISO / tek-04 / netprog.zip / NETPROG.TAR / record / parent15.c < prev    next >
C/C++ Source or Header  |  1989-12-17  |  2KB  |  86 lines

  1. /*
  2.  * This function copies standard input to "fd" and also copies
  3.  * everything from "fd" to standard output.
  4.  * In addition, all this data that is copied could also
  5.  * be recorded in a log file, if desired.
  6.  *
  7.  * This version fork's into two processes - one to copy stdin to fd,
  8.  * and one to copy fd to stdout.  This is required if you can't use
  9.  * select(2) or poll(2) on any of the three descriptors.
  10.  */
  11.  
  12. #include    <sys/types.h>
  13. #include    <signal.h>
  14.  
  15. #define    BUFFSIZE    512
  16.  
  17. static int    sigcaught;    /* set by signal handler */
  18.  
  19. pass_all(fd, childpid)
  20. int    fd;
  21. int    childpid;
  22. {
  23.     int        newpid, nread;
  24.     int        sig_term();
  25.     char        buff[BUFFSIZE];
  26.  
  27.     if ( (newpid = fork()) < 0) {
  28.         err_sys("parent1: can't fork");
  29.  
  30.     } else if (newpid == 0) {    /* child: stdin -> fd */
  31.         for ( ; ; ) {
  32.             nread = read(0, buff, BUFFSIZE);
  33.             if (nread < 0)
  34.                 err_sys("read error from stdin");
  35.             else if (nread == 0)
  36.                 break;        /* stdin EOF -> done */
  37.  
  38.             if (writen(fd, buff, nread) != nread)
  39.                 err_sys("writen error to stream pipe");
  40.         }
  41.         kill(getppid(), SIGTERM);    /* kill parent */
  42.         exit(0);
  43.     }
  44.     /* parent: fd -> stdout */
  45.  
  46. #ifdef    SIGTTIN
  47.     siginterrupt(SIGTERM, 1);    /* interrupt the system call */
  48. #endif
  49.  
  50.     sigcaught = 0;
  51.     signal(SIGTERM, sig_term);
  52.  
  53.     for ( ; ; ) {
  54.         if ( (nread = read(fd, buff, BUFFSIZE)) <= 0)
  55.             break;        /* error, EOF or signal; terminate */
  56.  
  57.         if (write(1, buff, nread) != nread)
  58.             err_sys("write error to stdout");
  59.     }
  60.  
  61.     /*
  62.      * If we get here either there was an EOF on the stream pipe,
  63.      * implying that the shell terminated, or the child process above
  64.      * terminated and we received its SIGTERM.
  65.      * If the shell terminated, we have to let the child process
  66.      * that we fork'ed above know this, so that it can break out
  67.      * of its read from the standard input.
  68.      * If we received the signal, the child is already gone, so we're done.
  69.      */
  70.  
  71.     if (sigcaught == 0)
  72.         kill(newpid, SIGTERM);
  73.  
  74.     return;        /* parent returns to caller */
  75. }
  76. /*
  77.  * If we get here, the child that was copying stdin to the IPC
  78.  * channel got an EOF or error.  It has notified us with a SIGTERM
  79.  * signal.  We set a flag for the parent process above.
  80.  */
  81.  
  82. sig_term()
  83. {
  84.     sigcaught = 1;        /* set flag */
  85. }
  86.